package app.goods.info.views;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

import org.apache.commons.lang3.StringUtils;

import app.goods.info.constants.ConstontValue;
import app.goods.info.constants.GlobalCache;
import app.goods.info.constants.UrlConstont;
import app.goods.info.services.domain.GoodsInfo;
import app.goods.info.services.domain.ShopInfo;
import app.goods.info.utils.FileReaderUtils;
import app.goods.info.utils.GeoUtil;
import app.goods.info.utils.HttpClientUtils;
import app.goods.info.utils.InterfaceUtils;
import app.goods.info.utils.ShopInfoUtils;
import app.goods.info.utils.UrlUtils;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class AllShopSettingFrame extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private DefaultTableModel tableModel;
	private JTable table;
	JFrame parentFrame;

	public AllShopSettingFrame(JFrame parentFrame) {
		this.parentFrame = parentFrame;
		setLayout(new BorderLayout());

		setBounds(10, 10, 500, 800);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		this.setBackground(Color.white);
		final JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		add(panel);

		JPanel buttonJPanel = new JPanel();
		JButton refeshButton = new JButton("刷新");
		refeshButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				refeshButton.setEnabled(false);
				refeshButton.setText("正在刷新商店列表。。。");
				SwingUtilities.invokeLater(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub
						String jsonString = FileReaderUtils.readFileQuikly(ConstontValue.ALL_SHOP_INFO);
						if(jsonString==null || jsonString.equals("")){
							jsonString = "[]";
						}
						List<ShopInfo> shopInfos = JSONUtil.toList(JSONUtil.parseArray(jsonString), ShopInfo.class);
						Optional<ShopInfo> maxInfo = shopInfos.stream().max(new Comparator<ShopInfo>() {

							@Override
							public int compare(ShopInfo o1, ShopInfo o2) {
								// TODO Auto-generated method stub
								return Integer.parseInt(o1.getShopNo())- Integer.parseInt(o2.getShopNo());
							}
						});
						int index = 0;
						if(maxInfo.isPresent()){
							 index = Integer.parseInt(maxInfo.get().getShopNo());
						}
						for (int i = index; i < index + 50; i++) {
							try {
								Thread.sleep(200);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							JSONObject result = ShopInfoUtils.getShopInfo(String.valueOf(i));

							System.out.println(result.toString());
							if (result == null || !result.getStr("code").equals("0")) {
								continue;
							}
							String shopNoString = result.getJSONObject("result").getStr("shop_no");
							String shopNameString = result.getJSONObject("result").getStr("shop_name");
							String shopAddress = result.getJSONObject("result").getStr("shop_address");
							ShopInfo shopInfo = new ShopInfo(shopNameString, shopNoString, ConstontValue.OFF);
							if (shopInfos.contains(shopInfo) && !shopInfos.get(shopInfos.indexOf(shopInfo))
									.getShopName().equals(shopInfo.getShopName())) {
								shopInfos.get(shopInfos.indexOf(shopInfo)).setShopName(shopInfo.getShopName());
							}
							if (!shopInfos.contains(shopInfo)) {
								shopInfo.setShopAddress(shopAddress);
								setShopInfoLocation(shopInfo);
								shopInfos.add(shopInfo);
							}

						}
						FileReaderUtils.writeJsonToFileByLine(JSONUtil.toJsonPrettyStr(shopInfos),
								ConstontValue.ALL_SHOP_INFO);
						GlobalCache.getInstance().setAllShopInfos(shopInfos);
						refeshButton.setEnabled(true);
						refeshButton.setText("刷新");
						table.setModel(getShopTableModel());
						table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
						table.getColumn("上下架").setCellRenderer(new ButtonRenderer());
						table.getColumn("上下架").setCellEditor(new ButtonEditor(new JCheckBox()));
						table.setShowGrid(true);
						table.repaint();
					}
				});

			}
		});

		JButton refreshLocationButton = new JButton("更新经纬度");
		JLabel tipLabel = new JLabel();
		refreshLocationButton.addActionListener(listner -> {
			tipLabel.setText("开始检查，自动刷新.....");
			refreshLocationButton.setEnabled(false);
			SwingUtilities.invokeLater(() -> {
				double[] bearings = { 0, 45, 90, 135, 180, 225, 270, 315 };
				List<ShopInfo> allShops = GlobalCache.getInstance().getAllShopInfos().stream()
						.filter(shopInfo -> shopInfo.getStatus().equals("ON")).collect(Collectors.toList());
				for (ShopInfo shopInfo : allShops) {
					List<GoodsInfo> result = getGoodsForShop(shopInfo);
					try {
						Thread.sleep(600);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					if (result.size() > 0) {
						continue;
					}
					jumpOutHere: for (int i = 0; i < 10; i++) {
						for (double bearing : bearings) {
							double[] newCoordinate = GeoUtil.calculateNewCoordinate(shopInfo.getLatitude(),
									shopInfo.getLongitude(), 500 * i, bearing);
							shopInfo.setLatitude(newCoordinate[0]);
							shopInfo.setLongitude(newCoordinate[1]);
							result = getGoodsForShop(shopInfo);
							try {
								Thread.sleep(600);
							} catch (InterruptedException e1) {
								e1.printStackTrace();
							}
							if (result.size() > 0) {
								break jumpOutHere;
							}
						}
					}
				}

				GlobalCache.getInstance().getAllShopInfos().removeAll(allShops);
				GlobalCache.getInstance().getAllShopInfos().addAll(allShops);
				GlobalCache.getInstance().getAllShopInfos().sort(new Comparator<ShopInfo>() {

					@Override
					public int compare(ShopInfo shopInfo1, ShopInfo shopInfo2) {
						// TODO Auto-generated method stub
						return Integer.parseInt(shopInfo1.getShopNo()) - Integer.parseInt(shopInfo2.getShopNo());
					}
				});
				FileReaderUtils.writeJsonToFileByLine(
						JSONUtil.toJsonPrettyStr(GlobalCache.getInstance().getAllShopInfos()),
						"configs/all_shops.json");
				InterfaceUtils.refreshShopList(parentFrame);
				tipLabel.setText("刷新结束");
				refreshLocationButton.setEnabled(true);
			});

		});
		buttonJPanel.setLayout(new BoxLayout(buttonJPanel, BoxLayout.X_AXIS));
		buttonJPanel.add(refeshButton);
		buttonJPanel.add(Box.createHorizontalStrut(20));
		buttonJPanel.add(refreshLocationButton);
		buttonJPanel.add(Box.createHorizontalStrut(20));
		buttonJPanel.add(tipLabel);
		add(buttonJPanel, BorderLayout.NORTH);

		final JScrollPane scrollPane = new JScrollPane();
		scrollPane.setAutoscrolls(true);
		panel.add(scrollPane);

		tableModel = getShopTableModel();

		table = new JTable(tableModel);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.getColumn("上下架").setCellRenderer(new ButtonRenderer());
		table.getColumn("上下架").setCellEditor(new ButtonEditor(new JCheckBox()));

		table.setShowGrid(true);

		// 设置列标题不能移动
		table.getTableHeader().setReorderingAllowed(false);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		scrollPane.setViewportView(table);

		// 设置列宽,并且当调整Panel时列宽也能相应的变化
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
//		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);  //若设置它，列宽永远固定
		table.getColumnModel().getColumn(0).setPreferredWidth(30);
		table.getColumnModel().getColumn(1).setPreferredWidth(100);
		table.getColumnModel().getColumn(2).setPreferredWidth(40);

		// 设置行高
		table.setRowHeight(30);
		setLocationRelativeTo(null);
		setAlwaysOnTop(true);
		setVisible(true);

	}

	private DefaultTableModel getShopTableModel() {
		List<ShopInfo> shops = new ArrayList<ShopInfo>(); // 从数据库中获取商家列表
		String jsonString = FileReaderUtils.readFileQuikly(ConstontValue.ALL_SHOP_INFO);
		shops.addAll(JSONUtil.toList(JSONUtil.parseArray(jsonString), ShopInfo.class));
		shops.sort(new Comparator<ShopInfo>() {

			@Override
			public int compare(ShopInfo o1, ShopInfo o2) {
				// TODO Auto-generated method stub
				return o2.getStatus().compareTo(o1.getStatus());
			}
		});
		int rowCount = shops.size();
		int columnCount = 4; // 商家名称和商家编码两个列
		Object[][] data = new Object[rowCount][columnCount];
		for (int i = 0; i < rowCount; i++) {
			ShopInfo shop = shops.get(i);
			data[i][0] = i + 1;
			data[i][1] = shop.getShopName(); // 商家名称
			data[i][2] = shop.getShopNo(); // 商家编码
			if (ConstontValue.ON.equals(shop.getStatus())) {
				data[i][3] = "下架"; // 商家编码
			} else {
				data[i][3] = "上架"; // 商家编码
			}
		}
		String[] columnNames = { "序号", "商家名称", "商家编码", "上下架" }; // 表格列名
		return new DefaultTableModel(data, columnNames);
	}

	public class ButtonRenderer extends JButton implements TableCellRenderer {
		/**
		 * 
		 */
		private static final long serialVersionUID = 7350159574781038380L;

		public ButtonRenderer() {
			setOpaque(true);
		}

		@Override
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
				int row, int column) {
			setText((value == null) ? "" : value.toString());

			if ("下架".equals(value)) {
				setBackground(Color.GREEN);
			}
			if ("上架".equals(value)) {
				setBackground(Color.LIGHT_GRAY);
			}
			// 情况一：启用/禁用按钮
			// 情况二：禁用按钮时，不显示按钮，显示空白
			// if(enableBooleans[column] - columnWithoutButton)
			// setEnabled(setEnabled(enableBooleans[column-columnWithoutButton]);
			// else
			// return null;
			return this;
		}

	}

	public class ButtonEditor extends DefaultCellEditor {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		protected JButton button;

		public ButtonEditor(JCheckBox checkBox) {
			super(checkBox);
			button = new JButton();
			button.setOpaque(true);
			button.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent arg0) {
					ButtonClick();
				}

			});
		}

		@Override
		public Component getTableCellEditorComponent(JTable table1, Object value, boolean isSelected, int row,
				int column) {
			String command = table1.getValueAt(row, column).toString();
			button.setText(command);
			return button;

		}

		// 若缺少此方法，点击按钮后将获取不到Button的Text值，将会显示false.
		@Override
		public Object getCellEditorValue() {
			return button.getText();
		}

		protected void ButtonClick() {
			int row = table.getSelectedRow();
			String shopNo = table.getValueAt(row, 2).toString();
			String shopName = table.getValueAt(row, 1).toString();
			ShopInfo shopInfo = new ShopInfo(shopName, shopNo, ConstontValue.OFF);
			shopInfo = GlobalCache.getInstance().getAllShopInfos()
					.get(GlobalCache.getInstance().getAllShopInfos().indexOf(shopInfo));
			String command = button.getText();
			if ("上架".equals(command)) {
				button.setBackground(Color.GREEN);
				button.setText("下架");
				shopInfo.setStatus(ConstontValue.ON);
			}
			if ("下架".equals(command)) {
				button.setBackground(Color.LIGHT_GRAY);
				button.setText("上架");
				shopInfo.setStatus(ConstontValue.OFF);
			}
			if (GlobalCache.getInstance().getAllShopInfos().contains(shopInfo)) {
				GlobalCache.getInstance().getAllShopInfos().remove(shopInfo);
				GlobalCache.getInstance().getAllShopInfos().add(shopInfo);
			}
			FileReaderUtils.writeJsonToFileByLine(JSONUtil.toJsonPrettyStr(GlobalCache.getInstance().getAllShopInfos()),
					"configs/all_shops.json");
			InterfaceUtils.refreshShopList(parentFrame);
		}
	}

	public static void main(String args[]) {
		try {
			GlobalCache.getInstance().initAllCache();
			new AllShopSettingFrame(null);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static List<GoodsInfo> getGoodsForShop(ShopInfo shopInfo) {
		List<GoodsInfo> result = new ArrayList<GoodsInfo>();
		String queryUrl = UrlConstont.CENTRALIZED_PROCUREMENT_GOODS_SHOP.concat("1" + "?");
		queryUrl = UrlUtils.getRequestUrl(queryUrl);
		queryUrl = queryUrl.concat("catalogue_no=").concat("2514").concat("&shop_no=").concat(shopInfo.getShopNo())
				.concat("&search_mode=1&sort_type=10&coordinate=").concat(String.valueOf(shopInfo.getLatitude()))
				.concat(",").concat(String.valueOf(shopInfo.getLongitude()));
		String responseBody = HttpClientUtils.get(queryUrl, UrlUtils.builQueryParameters());
		if (StringUtils.isNotEmpty(responseBody)) {
			String messageCode = JSONUtil.parseObj(responseBody).getStr("code");
			if ("0".equals(messageCode)) {
				JSONArray allGoodsArray = JSONUtil.parseObj(responseBody).getJSONObject("result").getJSONArray("list");
				if (allGoodsArray != null && allGoodsArray.size() > 0) {
					result.addAll(JSONUtil.toList(allGoodsArray, GoodsInfo.class));

				}
			}
		}
		return result;
	}

	private void setShopInfoLocation(ShopInfo shopInfo) {
		String address = shopInfo.getShopAddress();
		String url = "https://restapi.amap.com/v3/place/text";
		Map<String, String> queryMap = new HashMap<String, String>();
		queryMap.put("keywords", address);
		queryMap.put("output", "json");
		queryMap.put("city", "宿迁市");
		queryMap.put("key", "4b1109e7a4dff5ac4e90566536e11a36");
		queryMap.put("types", "公司");
		queryMap.put("extensions", "base");

		String res = HttpClientUtils.get1(url, queryMap);
		System.out.println(res);
		try {
			JSONObject result = JSONUtil.parseObj(res);
			if (result != null && result.getJSONArray("pois") != null && result.getJSONArray("pois").size() > 0) {
				JSONObject location = (JSONObject) result.getJSONArray("pois").get(0);
				shopInfo.setLatitude(Double.parseDouble(location.getStr("location").split(",")[1]));
				shopInfo.setLongitude(Double.parseDouble(location.getStr("location").split(",")[0]));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}